﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
using MasterDetailTemplate.Models;
using MasterDetailTemplate.Services;
using Xamarin.Forms.Extended;

namespace MasterDetailTemplate.ViewModels
{
    public class TimelineViewModel : INotifyPropertyChanged
    {
        /// <summary>
        /// 能否加载更多结果。
        /// </summary>
        private bool _canLoadMore;

        /// <summary>
        /// 事件存储。
        /// </summary>
        private IEventStorage _eventStorage;

        /// <summary>
        /// 事件集合。
        /// </summary>
        private InfiniteScrollCollection<Event> anniversaryEventCollection;

        /// <summary>
        /// 事件集合。
        /// </summary>
        public InfiniteScrollCollection<Event> AnniversaryEventCollection
        {
            get { return anniversaryEventCollection; }
            set
            {
                anniversaryEventCollection = value;
            }
        }

        /// <summary>
        /// 事件集合。
        /// </summary>
        private InfiniteScrollCollection<Event> countdownEventCollection;

        /// <summary>
        /// 事件集合。
        /// </summary>
        public InfiniteScrollCollection<Event> CountdownEventCollection
        {
            get { return countdownEventCollection; }
            set
            {
                countdownEventCollection = value;
            }
        }

        /// <summary>
        /// 事件
        /// </summary>
        public Event Event
        {
            get => _event;
            set
            {
                _event = value;
            }
        }

        /// <summary>
        /// 事件
        /// </summary>
        private Event _event;

        public TimelineViewModel(IEventStorage eventStorage)
        {
            _eventStorage = eventStorage;

            ParameterExpression parameter = Expression.Parameter(typeof(Event), "e");
            MemberExpression member = Expression.PropertyOrField(parameter, "Attribute");
            ConstantExpression constant = Expression.Constant(1);
            Whereanni = Expression.Lambda<Func<Event, bool>>(Expression.Equal(member, constant), parameter);

            AnniversaryEventCollection = new InfiniteScrollCollection<Event>();
            AnniversaryEventCollection.OnCanLoadMore = () => _canLoadMore;
            AnniversaryEventCollection.OnLoadMore = async () =>
            {
                Status = Loading;
                var events = await _eventStorage.GetEventsAsync(Whereanni,
                    AnniversaryEventCollection.Count, PageSize);
                events.Sort(new EventCompare());
                Status = string.Empty;
                if (events.Count < PageSize)
                {
                    _canLoadMore = false;
                    Status = NoMoreResult;
                }
                if (AnniversaryEventCollection.Count == 0 && events.Count == 0)
                {
                    Status = NoResult;
                }
                return events;
            };

            ParameterExpression parameter2 = Expression.Parameter(typeof(Event), "e");
            MemberExpression member2 = Expression.PropertyOrField(parameter2, "Attribute");
            ConstantExpression constant2 = Expression.Constant(2);
            Wherecount = Expression.Lambda<Func<Event, bool>>(Expression.Equal(member2, constant2), parameter2);

            CountdownEventCollection = new InfiniteScrollCollection<Event>();
            CountdownEventCollection.OnCanLoadMore = () => _canLoadMore;
            CountdownEventCollection.OnLoadMore = async () =>
            {
                Status = Loading;
                var events = await _eventStorage.GetEventsAsync(Wherecount,
                    CountdownEventCollection.Count, PageSize);
                events.Sort(new EventCompare());
                Status = string.Empty;
                if (events.Count < PageSize)
                {
                    _canLoadMore = false;
                    Status = NoMoreResult;
                }
                if (CountdownEventCollection.Count == 0 && events.Count == 0)
                {
                    Status = NoResult;
                }
                return events;
            };
            IsAnniversary = true;
        }

        /// <summary>
        /// 页面显示命令。
        /// </summary>
        public RelayCommand _pageAppearingCommand;

        /// <summary>
        /// 页面显示命令。
        /// </summary>
        public RelayCommand PageAppearingCommand =>
            _pageAppearingCommand ?? (_pageAppearingCommand =
                new RelayCommand(async () =>
                {
                    await PageAppearingCommandFunction();
                }));

        /// <summary>
        /// 页面显示命令函数。
        /// </summary>
        public async Task PageAppearingCommandFunction()
        {
            _canLoadMore = true;
            await AnniversaryEventCollection.LoadMoreAsync();
            await CountdownEventCollection.LoadMoreAsync();
        }

        /// <summary>
        /// 纪念日时间轴显示命令。
        /// </summary>
        public RelayCommand _anniversaryTimelineAppearingCommand;

        /// <summary>
        /// 纪念日时间轴显示命令。
        /// </summary>
        public RelayCommand AnniversaryTimelineAppearingCommand =>
            _anniversaryTimelineAppearingCommand ?? (_anniversaryTimelineAppearingCommand =
                new RelayCommand(async () =>
                {
                    await AnniversaryTimelineAppearingCommandFunction();
                }));

        /// <summary>
        /// 纪念日时间轴显示命令。
        /// </summary>
        public async Task AnniversaryTimelineAppearingCommandFunction()
        {
            _canLoadMore = true;
            IsAnniversary = true;
        }


        /// <summary>
        /// 倒数日时间轴显示命令。
        /// </summary>
        public RelayCommand _countdownTimelineAppearingCommand;

        /// <summary>
        /// 倒数日时间轴显示命令。
        /// </summary>
        public RelayCommand CountdownTimelineAppearingCommand =>
            _countdownTimelineAppearingCommand ?? (_countdownTimelineAppearingCommand =
                new RelayCommand(async () =>
                {
                    await CountdownTimelineAppearingCommandFunction();
                }));

        /// <summary>
        /// 倒数日时间轴显示命令。
        /// </summary>
        public async Task CountdownTimelineAppearingCommandFunction()
        {
            _canLoadMore = true;
            IsAnniversary = false;
        }

        /// <summary>
        /// 比较函数
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private static int DateCompare(Event x, Event y)
        {
            if (x.Date > y.Date)
            {
                return 1;
            }
            else if (x.Date == y.Date)
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }

        /// <summary>
        /// 事件排序类，实现排序接口
        /// </summary>
        class EventCompare : IComparer<Event>
        {
            public int Compare(Event x, Event y)
            {
                return DateCompare(x, y);
            }
        }


        /// <summary>
        /// 查询语句。
        /// </summary>
        public Expression<Func<Event, bool>> Whereanni
        {
            get => _whereanni;
            set
            {
                _whereanni = value;
            }
        }

        /// <summary>
        /// 查询语句。
        /// </summary>
        private Expression<Func<Event, bool>> _whereanni;

        /// <summary>
        /// 查询语句。
        /// </summary>
        public Expression<Func<Event, bool>> Wherecount
        {
            get => _wherecount;
            set
            {
                _wherecount = value;
            }
        }

        /// <summary>
        /// 查询语句。
        /// </summary>
        private Expression<Func<Event, bool>> _wherecount;

        /// <summary>
        /// 加载状态。
        /// </summary>
        public string Status
        {
            get => _status;
            set
            {
                _status = value;
            }
        }

        /// <summary>
        /// 加载状态。
        /// </summary>
        private string _status;

        /// <summary>
        /// 正在载入。
        /// </summary>
        public const string Loading = "正在载入";

        /// <summary>
        /// 没有满足条件的结果。
        /// </summary>
        public const string NoResult = "没有满足条件的结果";

        /// <summary>
        /// 没有更多结果。
        /// </summary>
        public const string NoMoreResult = "没有更多结果";

        /// <summary>
        /// 一次显示的事件数量。
        /// </summary>
        public const int PageSize = 15;

        /// <summary>
        /// 是否显示纪念日时间轴。
        /// </summary>
        private bool _isAnniversary;

        /// <summary>
        /// 是否显示纪念日时间轴。
        /// </summary>
        public bool IsAnniversary
        {
            get { return _isAnniversary; }
            set
            {
                _isAnniversary = value;
                NotifyPropertyChanged("IsAnniversary");
            }
        }

        /// <summary>
        /// 属性改变变量。
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 监控属性改变函数。
        /// </summary>
        /// <param name="propertyName">属性名</param>
        protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }
}
